﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.MissionViews.MissionCrosshair
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using TaleWorlds.Core;
using TaleWorlds.DotNet;
using TaleWorlds.Engine;
using TaleWorlds.Library;

#nullable disable
namespace TaleWorlds.MountAndBlade.View.MissionViews
{
  [DefaultView]
  public class MissionCrosshair : MissionView
  {
    private GameEntity[] _crosshairEntities;
    private GameEntity[] _arrowEntities;
    private float[] _gadgetOpacities;
    private const int GadgetCount = 7;

    public override void OnMissionScreenInitialize()
    {
      base.OnMissionScreenInitialize();
      this._crosshairEntities = new GameEntity[3];
      this._arrowEntities = new GameEntity[4];
      this._gadgetOpacities = new float[7];
      for (int index = 0; index < 3; ++index)
      {
        this._crosshairEntities[index] = GameEntity.CreateEmpty(this.Mission.Scene);
        string metaMeshName = index == 0 ? "crosshair_top" : (index == 1 ? "crosshair_left" : "crosshair_right");
        MetaMesh copy = MetaMesh.GetCopy(metaMeshName);
        int meshCount = copy.MeshCount;
        for (int meshIndex = 0; meshIndex < meshCount; ++meshIndex)
        {
          Mesh meshAtIndex = copy.GetMeshAtIndex(meshIndex);
          meshAtIndex.SetMeshRenderOrder(200);
          meshAtIndex.VisibilityMask = VisibilityMaskFlags.Final;
        }
        this._crosshairEntities[index].AddComponent((GameEntityComponent) copy);
        MatrixFrame identity = MatrixFrame.Identity;
        this._crosshairEntities[index].Name = metaMeshName;
        this._crosshairEntities[index].SetFrame(ref identity);
        this._crosshairEntities[index].SetVisibilityExcludeParents(false);
      }
      for (int index = 0; index < 4; ++index)
      {
        this._arrowEntities[index] = GameEntity.CreateEmpty(this.Mission.Scene);
        string metaMeshName = index == 0 ? "arrow_up" : (index == 1 ? "arrow_right" : (index == 2 ? "arrow_down" : "arrow_left"));
        MetaMesh copy = MetaMesh.GetCopy(metaMeshName);
        int meshCount = copy.MeshCount;
        for (int meshIndex = 0; meshIndex < meshCount; ++meshIndex)
        {
          Mesh meshAtIndex = copy.GetMeshAtIndex(meshIndex);
          meshAtIndex.SetMeshRenderOrder(200);
          meshAtIndex.VisibilityMask = VisibilityMaskFlags.Final;
        }
        this._arrowEntities[index].AddComponent((GameEntityComponent) copy);
        MatrixFrame identity = MatrixFrame.Identity;
        this._arrowEntities[index].Name = metaMeshName;
        this._arrowEntities[index].SetFrame(ref identity);
        this._arrowEntities[index].SetVisibilityExcludeParents(false);
      }
    }

    public override void OnMissionScreenTick(float dt)
    {
      base.OnMissionScreenTick(dt);
      bool flag = false;
      float[] numArray = new float[8];
      for (int index = 0; index < 7; ++index)
        numArray[index] = 0.0f;
      if (MBEditor.EditModeEnabled && ((NativeObject) this._crosshairEntities[0] == (NativeObject) null || (NativeObject) this._arrowEntities[0] == (NativeObject) null))
        return;
      this._crosshairEntities[0].SetVisibilityExcludeParents(false);
      this._crosshairEntities[1].SetVisibilityExcludeParents(false);
      this._crosshairEntities[2].SetVisibilityExcludeParents(false);
      this._arrowEntities[0].SetVisibilityExcludeParents(false);
      this._arrowEntities[1].SetVisibilityExcludeParents(false);
      this._arrowEntities[2].SetVisibilityExcludeParents(false);
      this._arrowEntities[3].SetVisibilityExcludeParents(false);
      if (this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.CutScene)
        return;
      double near = (double) this.MissionScreen.CombatCamera.Near;
      float num1 = (float) (4.6999998092651367 + ((double) this.MissionScreen.CombatCamera.HorizontalFov - 0.63999998569488525) * 7.1399998664855957);
      if (this.Mission.MainAgent != null)
      {
        Agent mainAgent = this.Mission.MainAgent;
        float num2 = this.MissionScreen.CameraViewAngle * ((float) Math.PI / 180f);
        float b = MathF.Tan((float) (((double) mainAgent.CurrentAimingError + (double) mainAgent.CurrentAimingTurbulance) * (0.5 / (double) MathF.Tan(num2 * 0.5f))));
        Vec2 vec2_1 = new Vec2(0.5f, 0.375f);
        Vec2 vec2_2 = new Vec2(0.0f, b);
        MatrixFrame frame1 = this.MissionScreen.CombatCamera.Frame;
        frame1.Elevate(-5f);
        frame1.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame1.Strafe(vec2_2.x);
        frame1.Advance(vec2_2.y);
        this._crosshairEntities[0].SetFrame(ref frame1);
        Vec2 vec2_3 = vec2_2;
        vec2_3.RotateCCW(2.268928f);
        MatrixFrame frame2 = this.MissionScreen.CombatCamera.Frame;
        frame2.Elevate(-5f);
        frame2.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame2.Strafe(vec2_3.x);
        frame2.Advance(vec2_3.y);
        this._crosshairEntities[1].SetFrame(ref frame2);
        Vec2 vec2_4 = vec2_2;
        vec2_4.RotateCCW(-2.268928f);
        MatrixFrame frame3 = this.MissionScreen.CombatCamera.Frame;
        frame3.Elevate(-5f);
        frame3.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame3.Strafe(vec2_4.x);
        frame3.Advance(vec2_4.y);
        this._crosshairEntities[2].SetFrame(ref frame3);
        MatrixFrame frame4 = this.MissionScreen.CombatCamera.Frame;
        frame4.Elevate(-5f);
        frame4.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame4.Strafe(0.0f);
        frame4.Advance(0.07499999f);
        this._arrowEntities[0].SetFrame(ref frame4);
        MatrixFrame frame5 = this.MissionScreen.CombatCamera.Frame;
        frame5.Elevate(-5f);
        frame5.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame5.Strafe(0.149999976f);
        frame5.Advance(-0.025000006f);
        this._arrowEntities[1].SetFrame(ref frame5);
        MatrixFrame frame6 = this.MissionScreen.CombatCamera.Frame;
        frame6.Elevate(-5f);
        frame6.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame6.Strafe(0.0f);
        frame6.Advance(-0.07499999f);
        this._arrowEntities[2].SetFrame(ref frame6);
        MatrixFrame frame7 = this.MissionScreen.CombatCamera.Frame;
        frame7.Elevate(-5f);
        frame7.rotation.ApplyScaleLocal(new Vec3(num1, num1, num1));
        frame7.Strafe(-0.15f);
        frame7.Advance(-0.025000006f);
        this._arrowEntities[3].SetFrame(ref frame7);
        WeaponInfo wieldedWeaponInfo = mainAgent.GetWieldedWeaponInfo(Agent.HandIndex.MainHand);
        float numberToCheck = MBMath.WrapAngle(mainAgent.LookDirection.AsVec2.RotationInRadians - mainAgent.GetMovementDirection().RotationInRadians);
        if (wieldedWeaponInfo.IsValid && !this.MissionScreen.IsViewingCharacter())
        {
          if (wieldedWeaponInfo.IsRangedWeapon && BannerlordConfig.DisplayTargetingReticule)
          {
            Vec2 rotationConstraint = mainAgent.GetBodyRotationConstraint();
            if (this.Mission.MainAgent.MountAgent == null || MBMath.IsBetween(numberToCheck, rotationConstraint.x, rotationConstraint.y))
            {
              numArray[0] = 0.9f;
              numArray[1] = 0.9f;
              numArray[2] = 0.9f;
            }
            else if (this.Mission.MainAgent.MountAgent != null && !MBMath.IsBetween(numberToCheck, rotationConstraint.x, rotationConstraint.y) && ((double) rotationConstraint.x < -0.10000000149011612 || (double) rotationConstraint.y > 0.10000000149011612))
              flag = true;
          }
          else if (wieldedWeaponInfo.IsMeleeWeapon)
          {
            Agent.ActionCodeType currentActionType = mainAgent.GetCurrentActionType(1);
            Agent.UsageDirection currentActionDirection = mainAgent.GetCurrentActionDirection(1);
            if (BannerlordConfig.DisplayAttackDirection && (currentActionType == Agent.ActionCodeType.ReadyMelee || currentActionDirection != Agent.UsageDirection.None))
            {
              if (currentActionType == Agent.ActionCodeType.ReadyMelee)
              {
                switch (mainAgent.AttackDirection)
                {
                  case Agent.UsageDirection.AttackUp:
                    numArray[3] = 0.7f;
                    break;
                  case Agent.UsageDirection.AttackDown:
                    numArray[5] = 0.7f;
                    break;
                  case Agent.UsageDirection.AttackLeft:
                    numArray[6] = 0.7f;
                    break;
                  case Agent.UsageDirection.AttackRight:
                    numArray[4] = 0.7f;
                    break;
                }
              }
              else
              {
                flag = true;
                switch (currentActionDirection)
                {
                  case Agent.UsageDirection.AttackEnd:
                    numArray[3] = 0.7f;
                    break;
                  case Agent.UsageDirection.DefendDown:
                    numArray[5] = 0.7f;
                    break;
                  case Agent.UsageDirection.DefendLeft:
                    numArray[6] = 0.7f;
                    break;
                  case Agent.UsageDirection.DefendRight:
                    numArray[4] = 0.7f;
                    break;
                }
              }
            }
            else if (BannerlordConfig.DisplayAttackDirection || BannerlordConfig.AttackDirectionControl == 0)
            {
              switch (mainAgent.PlayerAttackDirection())
              {
                case Agent.UsageDirection.AttackUp:
                  numArray[3] = 0.7f;
                  break;
                case Agent.UsageDirection.AttackDown:
                  numArray[5] = 0.7f;
                  break;
                case Agent.UsageDirection.AttackLeft:
                  numArray[6] = 0.7f;
                  break;
                case Agent.UsageDirection.AttackRight:
                  numArray[4] = 0.7f;
                  break;
              }
            }
          }
        }
      }
      for (int index = 0; index < 7; ++index)
      {
        float num3 = dt;
        float num4 = index >= 3 ? num3 * 3f : num3 * 5f;
        if ((double) numArray[index] > (double) this._gadgetOpacities[index])
        {
          this._gadgetOpacities[index] += 1.2f * num4;
          if ((double) this._gadgetOpacities[index] > (double) numArray[index])
            this._gadgetOpacities[index] = numArray[index];
        }
        else if ((double) numArray[index] < (double) this._gadgetOpacities[index])
        {
          this._gadgetOpacities[index] -= num4;
          if ((double) this._gadgetOpacities[index] < (double) numArray[index])
            this._gadgetOpacities[index] = numArray[index];
        }
        int num5 = (int) ((double) byte.MaxValue * (double) this._gadgetOpacities[index]);
        if (num5 > 0)
        {
          if (index < 3)
            this._crosshairEntities[index].SetVisibilityExcludeParents(true);
          else
            this._arrowEntities[index - 3].SetVisibilityExcludeParents(true);
        }
        int num6 = num5 << 24;
        if (index < 3)
          this._crosshairEntities[index].GetFirstMesh().Color = !flag ? (uint) (16777215 | num6) : (uint) (16711680 | num6);
        else
          this._arrowEntities[index - 3].GetFirstMesh().Color = !flag ? (uint) (16759569 | num6) : (uint) (3386111 | num6);
      }
    }
  }
}
